/* Copyright (C) 2012 Haowen Ning This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.liberty.android.fantastischmemo.downloader.google; import android.net.Uri; import android.util.JsonReader; import android.util.JsonToken; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; public class EntryFactory { private static SimpleDateFormat ISO8601_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); private EntryFactory() { throw new AssertionError("Don't call constructor"); } /* * Get a list of entries of the correct type. * clazz: the class type to return * inputStream, input stream from the URLConnection */ public static <T extends Entry> List<T> getEntries(Class<T> clazz, InputStream inputStream) throws XmlPullParserException, IOException { XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(true); XmlPullParser xpp = factory.newPullParser(); xpp.setInput(new BufferedReader(new InputStreamReader(inputStream))); int eventType = xpp.getEventType(); List<T> entryList = new ArrayList<T>(50); T entry = null; String lastTag = ""; while (eventType != XmlPullParser.END_DOCUMENT) { if(eventType == XmlPullParser.START_DOCUMENT) { } else if(eventType == XmlPullParser.START_TAG) { lastTag = xpp.getName(); if(xpp.getName().equals("entry")) { try { entry = clazz.newInstance(); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } } } else if(eventType == XmlPullParser.END_TAG) { if(xpp.getName().equals("entry")) { entryList.add(entry); entry = null; } } else if(eventType == XmlPullParser.TEXT) { if(entry != null && lastTag.equals("id")) { // Get the last part of the uri, as it is the id. entry.setId(Uri.parse(xpp.getText()).getLastPathSegment()); } if(entry != null && lastTag.equals("title")) { entry.setTitle(xpp.getText()); } if(entry != null && lastTag.equals("updated")) { try { entry.setUpdateDate(ISO8601_FORMATTER.parse(xpp.getText())); } catch (ParseException e) { e.printStackTrace(); } } } eventType = xpp.next(); } return entryList; } /** * Parse the JSON format like this: * "kind": "drive#fileList", * "etag": "\"dM4Z0GasI3ekQlrgb3F8B4ytx24/bhMYFq5sxQUJKZ2H3LNeBmBcr2E\"", * "selfLink": "https://www.googleapis.com/drive/v2/files?q=title+%3D+'IMG_5652.jpg'", * "items": [..ITEM TYPE HERE.] */ public static <T extends Entry> List<T> getEntriesFromDriveApi(Class<T> clazz, InputStream inputStream) throws IOException { List<T> entryList = new ArrayList<T>(50); JsonReader jsonReader = null; String name = ""; try { jsonReader = new JsonReader(new InputStreamReader(inputStream, "UTF-8")); jsonReader.beginObject(); while (jsonReader.hasNext()) { if (jsonReader.peek() != JsonToken.NAME) { jsonReader.skipValue(); continue; } name = jsonReader.nextName(); if (name.equals("items") && jsonReader.peek() != JsonToken.NULL) { jsonReader.beginArray(); while (jsonReader.hasNext()) { entryList.add(getEntryFromJsonReader(clazz, jsonReader)); } jsonReader.endArray(); } } jsonReader.endObject(); } finally { if (jsonReader != null) { jsonReader.close(); } } return entryList; } public static <T extends Entry> T getEntryFromDriveApi(Class<T> clazz, InputStream inputStream) throws IOException { JsonReader jsonReader = null; try { jsonReader = new JsonReader(new InputStreamReader(inputStream, "UTF-8")); return getEntryFromJsonReader(clazz, jsonReader); } finally { if (jsonReader != null) { jsonReader.close(); } } } /** * Parse single entry from json reader * * The entry is like below: * { * "kind": "drive#file", * "id": "0B2Ipwyo9TOxYVmEwZWlLdlFCN1E", * "etag": "\"dM4Z0GasI3ekQlrgb3F8B4ytx24/MTQyNDg0NTE5OTM0MA\"", * "selfLink": "https://www.googleapis.com/drive/v2/files/0B2Ipwyo9TOxYVmEwZWlLdlFCN1E", * "webContentLink": "https://docs.google.com/uc?id=0B2Ipwyo9TOxYVmEwZWlLdlFCN1E&export=download", * "alternateLink": "https://docs.google.com/file/d/0B2Ipwyo9TOxYVmEwZWlLdlFCN1E/edit?usp=drivesdk", * "iconLink": "https://ssl.gstatic.com/docs/doclist/images/icon_11_image_list.png", * "thumbnailLink": "https://lh4.googleusercontent.com/XpCSGp9RcABx5ST3bKKb1HWcugDA-jnJiy8vIe04WF_sD$ 5z0sLX11PRHkydxdHoI5ylgQ=s220", * "title": "IMG_5652.jpg", * "mimeType": "image/jpeg", * "labels": { * "starred": false, * "hidden": false, * "trashed": false, * "restricted": false, * "viewed": false * }, * "createdDate": "2015-02-25T06:19:59.340Z", * "modifiedDate": "2015-02-25T06:19:59.340Z", * "modifiedByMeDate": "2015-02-25T06:19:59.340Z", * "markedViewedByMeDate": "1970-01-01T00:00:00.000Z", * "version": "133505", * ,.... * } */ private static <T extends Entry> T getEntryFromJsonReader(Class<T> clazz, JsonReader jsonReader) throws IOException { String name = ""; T entry; try { entry = clazz.newInstance(); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } jsonReader.beginObject(); // item object while (jsonReader.hasNext()) { name = jsonReader.nextName(); if (name.equals("id") && jsonReader.peek() != JsonToken.NULL) { entry.setId(jsonReader.nextString()); } else if (name.equals("title") && jsonReader.peek() != JsonToken.NULL) { entry.setTitle(jsonReader.nextString()); } else if (name.equals("modifiedDate") && jsonReader.peek() != JsonToken.NULL) { try { entry.setUpdateDate(ISO8601_FORMATTER.parse(jsonReader.nextString())); } catch (ParseException e) { throw new RuntimeException(e); } } else { jsonReader.skipValue(); } } jsonReader.endObject(); return entry; } }